# -*- coding: utf-8 -*-
"""
@author: luhx
@file: formula.py
@time: 2023/7/10 9:35
@desc:
"""

from base.BaseCD import MA, MACD
from base.BaseCD import CROSX
from kds_util.user_logbook import user_log as logger

CROSS_JX = 1  # 金叉
CROSS_SX = -1  # 死叉


def update_jx_sx_state(jx, state):
    """更新金死叉状态"""
    if jx == 1:
        state = 1
    elif jx == -1:
        state = -1
    else:
        if state == 0:
            return 0
        else:
            state = abs(state) // state + state
    return state


# %%
class CDBASE20:
    """20均线金死叉"""

    def __init__(self):
        self.REFC, self.REFMA = 0, 0
        self.MA20 = MA(20)
        self.state = 0  # 当前状态，默认为0
        self.count = 0

    def input(self, price, k_num=20):
        """传入价格,如果与20均金叉，返回1，死叉，返回-1，
        没有状态，返回0，
        金叉而未死叉，返回>1的数，
        死叉而未金叉，返回小于-1的数"""
        self.count += 1
        self.MA20.input(price, k_num)
        jx_sx = CROSX(price, self.MA20.ma, self.REFC, self.REFMA) == 1  # 金叉
        self.REFC, self.REFMA = price, self.MA20.ma
        self.state = update_jx_sx_state(jx_sx, self.state)
        return self.state


##########################################################################################


class DoubleMA:
    """双均线策略"""

    def __init__(self):
        self.MA20 = MA(20)
        self.MA60 = MA(60)
        self.refMA20 = self.refMA60 = 0
        self.refSxMA20, self.refJxMA20 = [], []
        self.state = 0
        self.buy_sell = 0   # 1 买入,-1 卖出

    def double_ma_input(self, price):
        self.refMA20, self.refMA60 = self.MA20.ma, self.MA60.ma
        self.MA20.input(price, 20)
        self.MA60.input(price, 60)
        jx_sx = CROSX(self.MA20.ma, self.MA60.ma, self.refMA20, self.refMA60)
        self.state = update_jx_sx_state(jx_sx, self.state)
        if jx_sx == 1:
            self.refJxMA20.append(self.MA20.ma)
            if len(self.refJxMA20) > 3:
                self.refJxMA20.pop(0)
        elif jx_sx == -1:
            self.refSxMA20.append(self.MA20.ma)
            if len(self.refSxMA20) > 3:
                self.refSxMA20.pop(0)
        if 1 <= self.state <= 1:
            self.buy_sell = 1
        elif -1 >= self.state >= -1:
            self.buy_sell = -1
        else:
            self.buy_sell = 0
        return self.buy_sell

    def __str__(self):
        js_statue = f"{['金叉', '死叉', '无状态'][0 if self.state > 0 else 1 if self.state < 0 else 2]}"
        count = f"{['', str(abs(self.state)-1)][0 if self.state == 0 else 1]}"
        return f"{js_statue}{count}"

    def __repr__(self):
        return self.__str__()


class MACDDivergence:  # MACD背离指标
    """MACD背离指标
    最完美形态为三次背离
    次完美为前两次背离，第三次或是股价微跌，死叉下移，或是股价微涨，死叉微上移，即不成比例关系（针对多头背离）
    """

    def __init__(self, mark=0):
        self.MACD: MACD = MACD()
        self.up_0_sc = []  # 0轴以上死叉
        self.ref_macd, self.ref_dea, self.ref_dif = self.MACD.macd, self.MACD.dea, self.MACD.dif
        self.using_flag = False  # 已经使用过
        self.signal = 0  # 默认为0， 有信号为1, 止损为-2， 信号第一目标完成为4， 全部完成为0
        self.prices = []

    def set_used(self):
        self.using_flag = True

    def input(self, kline):
        price = kline.close
        self.ref_macd, self.ref_dea, self.ref_dif = self.MACD.macd, self.MACD.dea, self.MACD.dif
        self.MACD.input(price)
        if self.MACD.dif < 0:
            self.up_0_sc.clear()  # 0轴以下清空
            return
        if len(self.up_0_sc) > 1:
            if not (self.up_0_sc[0][0] < self.up_0_sc[1][0] and self.up_0_sc[0][1] > self.up_0_sc[1][1]):
                self.up_0_sc.pop(0)  # 没有发生背离，将第一个点清除出去
        if self.signal == 0 and CROSX(self.MACD.dif, self.MACD.dea, self.ref_dif, self.ref_dea) == -1:
            self.up_0_sc.append([price, self.MACD.dif])
        if self.signal == 0 and len(self.up_0_sc) == 3:
            if self.up_0_sc[0][0] < self.up_0_sc[1][0] and self.up_0_sc[0][1] > self.up_0_sc[1][1]:
                if self.up_0_sc[1][0] < self.up_0_sc[2][0] and self.up_0_sc[1][1] > self.up_0_sc[2][1]:
                    self.signal = 1
                    self.prices = [self.up_0_sc[i][1] for i in range(len(self.up_0_sc))]

        if self.signal == 1 or self.signal == 4:
            # 止损
            max_price = max(self.prices)
            min_price = min(self.prices)
            if price > max_price:
                self.signal = -2
            # 止赢
            if price < min_price:
                self.signal = 4
            if self.MACD.dif >= self.MACD.dea:
                self.signal = 0  # 正常结束
                self.up_0_sc.clear()
                self.prices.clear()

#
# class MACDWithDivergence:  # MACD背离
#     """MACD背离指标"""
#
#     def __init__(self, mark=0):
#         self.MACD: MACD = MACD()
#         self.up_0_sc = []  # 0轴以上死叉
#         self.datas = []
#         self.k_id = 0
#
#     def add_data(self, price):
#         self.k_id += 1
#         self.datas.append([self.k_id, price])
#         if len(self.datas) > 100:
#             del self.datas[0]
#
#     def double_ma_input(self, kline):
#         price = kline.close
#         self.MACD.double_ma_input(price)
#         self.add_data(price)    # 加入缓存中
#         if CROSX(self.MACD.dif, self.MACD.dea, self.MACD.REFdif, self.MACD.REFdea) == -1 and self.MACD.macd > 0:
#             self.up_0_sc.append([price, self.MACD.dea])  # 0轴之上的死叉
#         if len(self.up_0_sc) > 1:
#             if not (self.up_0_sc[0][0] < self.up_0_sc[1][0] and self.up_0_sc[0][1] > self.up_0_sc[1][1]):
#                 self.up_0_sc.pop(0)  # 没有发生背离，将第一个点清除出去
#
#         if self.MACD.dea < 0:
#             self.up_0_sc.clear()  # 0轴以下清空
#             return
